package com.salesmanager.core.business.category.model;


import com.salesmanager.core.business.category.model.status.CategoryStatus;
import com.salesmanager.core.business.common.model.audit.AuditListener;
import com.salesmanager.core.business.common.model.audit.AuditSection;
import com.salesmanager.core.business.common.model.audit.Auditable;
import com.salesmanager.core.business.generic.model.SalesManagerEntity;
import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.*;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Entity
@EntityListeners(value = AuditListener.class)
@Table(name = "CATEGORY")
//@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Category extends SalesManagerEntity<Long, Category> implements Auditable {
	private static final long serialVersionUID = -846291242449186747L;
	
	@Id
	@Column(name = "CATEGORY_ID", unique=true, nullable=false)
	@TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CATEGORY_SEQ_NEXT_VAL",initialValue = 100000, allocationSize = 1)
	@GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
	private Long id;

	@Embedded
	private AuditSection auditSection = new AuditSection();

	@Column(name = "PRICE_INTERVAL", length=50)
    private String priceInterval;

	@ManyToOne
	@JoinColumn(name = "PARENT_ID")
	private Category parent;
	
	@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, orphanRemoval = true)
	private List<Category> categories = new ArrayList<Category>();

//    @ManyToMany(mappedBy = "categories")
//    private Set<Product> products = new HashSet<Product>();

	@NotEmpty
	@Column(name="NAME", nullable = false, length=120)
	private String name;

	@Column(name="TITLE", length=100)
	private String title;

//    @Column(name="SEF_URL", length=120)
//    private String seUrl;

    @Column(name="META_KEYWORDS")
    private String metatagKeywords;

	@Column(name="DESCRIPTION")
	@Type(type = "org.hibernate.type.StringClobType")
	private String description;
	
	@Column(name = "CATEGORY_IMAGE", length=100)
	private String categoryImage;

	@Column(name = "THEME_IMAGE", length=100)
	private String themeImage;

	@Transient
	private InputStream themeImageFile;

	@Column(name = "SORT_ORDER")
	private Integer sortOrder = 0;

    @Enumerated(value = EnumType.STRING)
    @Column(name = "CATEGORY_STATUS")
    private CategoryStatus categoryStatus;

	@Column(name = "VISIBLE")
	private boolean visible = true;

	@Column(name = "DEPTH")
	private Integer depth;

	@Column(name = "LINEAGE")
	private String lineage;

    @Column(name = "MARK",columnDefinition = "INT(1) COMMENT '角标 1：应季 2：反季'")
	private Integer mark;

	@NotEmpty
	@Column(name="CODE", length=100, nullable=false)
	private String code;

//    public String getSeUrl() {
//        return seUrl;
//    }
//
//    public void setSeUrl(String seUrl) {
//        this.seUrl = seUrl;
//    }

    public String getMetatagKeywords() {
        return metatagKeywords;
    }

    public void setMetatagKeywords(String metatagKeywords) {
        this.metatagKeywords = metatagKeywords;
    }


    //    @ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.REFRESH})
//    @JoinTable(name = "CATEGORY_SEASON_MAP", joinColumns = {
//            @JoinColumn(name = "CATEGORY_ID", nullable = false, updatable = false) }
//            ,
//            inverseJoinColumns = { @JoinColumn(name = "SEASON_ID",
//                    nullable = false, updatable = false) }
//    )
//    @Cascade({
//            org.hibernate.annotations.CascadeType.DETACH,
//            org.hibernate.annotations.CascadeType.LOCK,
//            org.hibernate.annotations.CascadeType.REFRESH,
//            org.hibernate.annotations.CascadeType.REPLICATE
//
//    })
//    private Set<Season> seasons = new HashSet<Season>();

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public Category() {
	}

	@Override
	public Long getId() {
		return this.id;
	}

	@Override
	public void setId(Long id) {
		this.id = id;
	}
	
	@Override
	public AuditSection getAuditSection() {
		return auditSection;
	}
	
	@Override
	public void setAuditSection(AuditSection auditSection) {
		this.auditSection = auditSection;
	}

	public static long getSerialVersionUID() {
		return serialVersionUID;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Integer getMark() {
        return mark;
    }

    public void setMark(Integer mark) {
        this.mark = mark;
    }

    public String getCategoryImage() {
		return categoryImage;
	}

	public void setCategoryImage(String categoryImage) {
		this.categoryImage = categoryImage;
	}

	public Integer getSortOrder() {
		return sortOrder;
	}

	public void setSortOrder(Integer sortOrder) {
		this.sortOrder = sortOrder;
	}

	public boolean isVisible() {
		return visible;
	}

	public void setVisible(boolean visible) {
		this.visible = visible;
	}

	public Integer getDepth() {
		return depth;
	}

	public void setDepth(Integer depth) {
		this.depth = depth;
	}

	public String getLineage() {
		return lineage;
	}

	public void setLineage(String lineage) {
		this.lineage = lineage;
	}

	public Category getParent() {
		return parent;
	}

	public void setParent(Category parent) {
		this.parent = parent;
	}

    public CategoryStatus getCategoryStatus() {
        return categoryStatus;
    }

    public void setCategoryStatus(CategoryStatus categoryStatus) {
        this.categoryStatus = categoryStatus;
    }

	public List<Category> getCategories() {
		return categories;
	}

	public void setCategories(List<Category> categories) {
		this.categories = categories;
	}

//    public Set<Product> getProducts() {
//        return products;
//    }
//
//    public void setProducts(Set<Product> products) {
//        this.products = products;
//    }
//
//	public void addSubCategory(Category subCate){
//		categories.add(subCate);
//	}
//
//    public Set<Season> getSeasons() {
//        return seasons;
//    }
//
//    public void setSeasons(Set<Season> seasons) {
//        this.seasons = seasons;
//    }

    @Transient
	private MultipartFile image = null;
	
	@Transient
	public MultipartFile getImage() {
		return image;
	}
	@Transient
	public void setImage(MultipartFile image) {
		this.image = image;
	}

	public String getThemeImage() {
		return themeImage;
	}

	public void setThemeImage(String themeImage) {
		this.themeImage = themeImage;
	}

	public InputStream getThemeImageFile() {
		return themeImageFile;
	}

	public void setThemeImageFile(InputStream themeImageFile) {
		this.themeImageFile = themeImageFile;
	}

    public String getPriceInterval() {
        return priceInterval;
    }

    public void setPriceInterval(String priceInterval) {
        this.priceInterval = priceInterval;
    }
}
